package cz.cvut.fit.web.nakupniSeznam.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cz.cvut.fit.web.nakupniSeznam.data.IEntity;

public abstract class GenericDAO<E extends IEntity> {
	
	public static final String SAVE_COMPLETE = "saving complete";
	public static final String SAVE_FAILED = "saving failed";
	public static final String REMOVE_COMPLETE = "removing complete";
	public static final String REMOVE_FAILED = "removing failed";

	protected final Logger LOG = LoggerFactory.getLogger(getEntityClass());
	protected EntityManager em = EMF.get().createEntityManager();

	protected abstract String getAllQueryName();

	protected abstract Class<E> getEntityClass();
	
	public void refresh(E entity) {
		this.em.refresh(entity);
	}
	
	public Long save(E entity) {
		EntityTransaction trans = this.em.getTransaction();
		trans.begin();
		try {
			if (entity.getId() == null) {
				em.persist(entity);
				em.refresh(entity);
				assert entity.getId() != null;
			} else {
				em.merge(entity);
			}
			trans.commit();
			LOG.debug(GenericDAO.SAVE_COMPLETE);
		} finally {
			if (trans.isActive()) {
				trans.rollback();
				LOG.debug(GenericDAO.SAVE_FAILED);
			}
		}
		return entity.getId();
	}

	public List<E> getAll() {
		Query q = em.createNamedQuery(this.getAllQueryName());

		@SuppressWarnings("unchecked")
		List<E> res = q.getResultList();
		return res;
	}

	public E getById(Long id) {
		return (E) this.em.find(this.getEntityClass(), id);
	}

	public void remove(Long id) {
		IEntity entity = this.getById(id);

		EntityTransaction trans = this.em.getTransaction();
		trans.begin();
		try {
			this.em.remove(entity);
			trans.commit();
			LOG.debug(GenericDAO.REMOVE_COMPLETE);
		} finally {
			if (trans.isActive()) {
				trans.rollback();
				LOG.debug(GenericDAO.REMOVE_FAILED);
			}
		}
	}
}
